#include "stdafx.h"
#include "XShapeImpl.h"

#include "Util.h"
#include "UIUtil.h"

#include "IntSkinImpl.h"
#include "Colorize.h"

template <class I>
CXShapeImpl<I>::CXShapeImpl()
{
    m_ShapeType = Shape_Rect;
    m_nBorderWidth = 1;
    m_clrBorder = RGB(255, 255, 255);
    m_nBorderCorner = 5;
    m_clrContent = RGB(255, 255, 255);

    m_dwFlags = 0;
    m_dwColorizeValue = 0;

    ChangePen();
    ChangeBrush();
}

template <class I>
CXShapeImpl<I>::~CXShapeImpl()
{
}

//////////////////////////////////////////////////////////////////////////
// IXShape
template <class I>
void CXShapeImpl<I>::put_ShapeType(IN ShapeType type)
{
    if(m_ShapeType != type)
    {
        m_ShapeType = type;
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::put_BorderWidth(IN int nBorderWidth)
{
    if(m_nBorderWidth != nBorderWidth)
    {
        m_nBorderWidth = nBorderWidth;
        ChangePen();
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::put_BorderColor(IN COLORREF clrBorder)
{
    if(m_clrBorder != clrBorder)
    {
        m_clrBorder = clrBorder;
        ChangePen();
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::put_BorderCorner(IN int nBorderCorner)
{
    if(m_nBorderCorner != nBorderCorner)
    {
        m_nBorderCorner = nBorderCorner;
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::put_ContentColor(IN COLORREF clrContent)
{
    if(m_clrContent != clrContent)
    {
        m_clrContent = clrContent;
        ChangeBrush();
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::put_ContentTransparent(IN BOOL bTransparent)
{
    if(IntSkinImpl::CheckFlags(m_dwFlags, ShapeFlag_ContentTransparent) != (!!bTransparent))
    {
        m_dwFlags = IntSkinImpl::ModifyFlags(m_dwFlags, ShapeFlag_ContentTransparent, bTransparent);
        ChangeBrush();
        Invalidate();
    }
}

//////////////////////////////////////////////////////////////////////////
// IXFrame

template <class I>
void CXShapeImpl<I>::Draw(XCANVAS xCanvas, const RECT& rcDraw)
{
    HGDIOBJ hOldPen = ::SelectObject((HDC)xCanvas, m_hPen);
    HGDIOBJ hOldBrush = ::SelectObject((HDC)xCanvas, m_hBrush);

    RECT rcWnd;
    get_WindowRect(&rcWnd);
    switch(m_ShapeType)
    {
    case Shape_RoundRect:
        ::RoundRect((HDC)xCanvas, rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, m_nBorderCorner, m_nBorderCorner);
        break;
    case Shape_Rect:
        ::Rectangle((HDC)xCanvas, rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom);
        break;
    case Shape_Line:
        ::MoveToEx((HDC)xCanvas, rcWnd.left, rcWnd.top, NULL);
        ::LineTo((HDC)xCanvas, rcWnd.right, rcWnd.bottom);
        break;
    }

    ::SelectObject((HDC)xCanvas, hOldPen);
    ::SelectObject((HDC)xCanvas, hOldBrush);

    superclass::Draw(xCanvas, rcDraw);
}

//////////////////////////////////////////////////////////////////////////
// IXBaseObj
template <class I>
void CXShapeImpl<I>::OnFinalRelease()
{
    superclass::OnFinalRelease();

    if(m_hPen != NULL)
    {
        ::DeleteObject(m_hPen);
        m_hPen = NULL;
    }
    if(m_hBrush != NULL)
    {
        ::DeleteObject(m_hBrush);
        m_hBrush = NULL;
    }
}

//////////////////////////////////////////////////////////////////////////
template <class I>
void CXShapeImpl<I>::ChangePen()
{
    if(m_hPen != NULL)
    {
        ::DeleteObject(m_hPen);
    }
    COLORREF clrBorder = m_clrBorder;
    if(IntSkinImpl::CheckFlags(m_dwFlags, ShapeFlag_Colorize))
    {
        clrBorder = Colorize::AdjustColorPixel(clrBorder, GetRValue(m_dwColorizeValue), GetGValue(m_dwColorizeValue), GetBValue(m_dwColorizeValue));
    }
    m_hPen = ::CreatePen(PS_SOLID, m_nBorderWidth, clrBorder);
}

template <class I>
void CXShapeImpl<I>::ChangeBrush()
{
    if(m_hBrush != NULL)
    {
        ::DeleteObject(m_hBrush);
    }
    if(IntSkinImpl::CheckFlags(m_dwFlags, ShapeFlag_ContentTransparent))
        m_hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
    else
    {
        COLORREF clrContent = m_clrContent;
        if(IntSkinImpl::CheckFlags(m_dwFlags, ShapeFlag_Colorize))
        {
            clrContent = Colorize::AdjustColorPixel(clrContent, GetRValue(m_dwColorizeValue), GetGValue(m_dwColorizeValue), GetBValue(m_dwColorizeValue));
        }
        m_hBrush = ::CreateSolidBrush(clrContent);
    }
}

//////////////////////////////////////////////////////////////////////////
// CXFrameImpl
template <class I>
void CXShapeImpl<I>::OnColorizeEnabled(BOOL bEnabled)
{
    if(IntSkinImpl::CheckFlags(m_dwFlags, ShapeFlag_Colorize) != (!!bEnabled))
    {
        m_dwFlags = IntSkinImpl::ModifyFlags(m_dwFlags, ShapeFlag_Colorize, bEnabled);
        Invalidate();
    }
}

template <class I>
void CXShapeImpl<I>::OnColorized(int hue, int sat, int light)
{
    m_dwFlags = IntSkinImpl::ModifyFlags(m_dwFlags, ShapeFlag_Colorize, TRUE);
    m_dwColorizeValue = RGB(hue, sat, light);
    ChangePen();
    ChangeBrush();
    Invalidate();
}
